<template>
  <div>
    <showFunction></showFunction>
    <header>
      <div class="top">excel的导入导出</div>
    </header>
    <section>
      <div class="export">
        <el-button @click="exportExcel" type="primary"
          >导出并下载Excel</el-button
        >
        <div>{{ tableData }}</div>
      </div>
      <div class="import">
        <el-button @click="importExcel" type="warning">导入Excel</el-button>
        <input hidden type="file" ref="fileInput" @change="onChange" />
        <div>
          {{
            importExcelResult
              ? '导入Excel的数据' + importExcelResult
              : '导入Excel的数据'
          }}
        </div>
      </div>
    </section>
  </div>
</template>
<script setup lang="ts">
  import { ref } from 'vue'
  import { read, utils, writeFileXLSX } from 'xlsx'
  import showFunction from '@/components/showfunction.vue'

  // 导出Excel
  let tableData = ref([
    { id: 1, name: '张三', age: 20 },
    { id: 2, name: '李四', age: 25 },
    { id: 3, name: '王五', age: 30 },
  ])
  const exportExcel = () => {
    // 创建一个新的工作簿
    const workbook = utils.book_new()
    // 创建一个工作表 要求为对象数组格式
    const worksheet = utils.json_to_sheet(tableData.value)
    // 把工作表添加到工作簿  Data为工作表名称
    utils.book_append_sheet(workbook, worksheet, 'Data')
    // 改写表头
    utils.sheet_add_aoa(worksheet, [['id', '姓名', '年龄']], { origin: 'A1' })
    // 导出方法进行导出
    writeFileXLSX(workbook, '前端导出的Excel.xlsx')
  }

  // 导入Excel
  const importExcelResult = ref()
  const fileInput = ref()
  const importExcel = () => {
    fileInput.value.click()
  }
  // 核心业务
  const onChange = async () => {
    // 获取文件
    const rawFile = fileInput.value.files[0]
    if (!rawFile) return
    const res = await readExcelData(rawFile)
    console.log(res)

    importExcelResult.value = res

    console.log(
      URL.createObjectURL(
        new Blob([importExcelResult.value], {
          type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        })
      )
    )
  }
  const readExcelData = (file: any) => {
    return new Promise((resolve: any) => {
      // console.log(file)
      // 1.利用h5的FileReader对象读取文件，创建reader实例
      const reader = new FileReader()
      // 2. readAsBinaryString 是 FileReader 的一个方法，用于读取文件的内容，并将它作为一个二进制字符串返回。当文件读取操作完成时，会触发 FileReader 的 onload 事件，并且可以通过 FileReader 的 result 属性获取到读取到的二进制字符串。
      reader.readAsArrayBuffer(file)
      reader.onload = (e: any) => {
        // xlsx提供的read方法将二进制数据读取为表数据 binary: 二进制数据
        const work = read(e.target.result, { type: 'binary' })
        // 获取第一份工作薄 work.Sheets是Excel文件中所有sheet的数据集合
        const firstSheets = work.Sheets[work.SheetNames[0]]
        //  利用ustils的sheet_to_json方法将表数据转换为json对象数组
        const data = utils.sheet_to_json(firstSheets)
        resolve(data)
      }
    })
  }
</script>

<style scoped lang="less">
  @import './index.scss';
</style>
